package com.vsu.bookstore.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vsu.bookstore.mvc.model.bean.BookStoreItem;

@SuppressWarnings("serial")
public class UserSession implements Serializable
{
  private final List<Integer> votedIds = new ArrayList<Integer>();

  private final BeanItemContainer<BookStoreItem> cartContainer = new BeanItemContainer<BookStoreItem>(BookStoreItem.class);

  public UserSession()
  {
  }

  public BookStoreItem addToCart(final Item item)
  {
    final BookStoreItem bean = DataUtils.getBeanByItem(item);
    final BeanItem<BookStoreItem> bi = cartContainer.getItem(bean);
    if (bi == null)
    {
      cartContainer.addBean(bean);
      return bean;
    }
    bi.getBean().increaseQuantity(1);
    return bi.getBean();
  }

  private void addVoted(final Integer id)
  {
    votedIds.add(id);
  }

  public void clear()
  {
    cartContainer.removeAllItems();
    votedIds.clear();
  }

  public BeanItemContainer<BookStoreItem> getCartContainer()
  {
    return cartContainer;
  }

  public String getPurchaseMessage()
  {
    final Collection<BookStoreItem> ids = cartContainer.getItemIds();
    final Iterator<BookStoreItem> it = ids.iterator();
    final StringBuilder result = new StringBuilder();
    result.append("Thanks for purchase, that's the stuff u've got so far:");
    while (it.hasNext())
    {
      final BookStoreItem item = it.next();
      result.append("\n" + item.getQuantity() + " x " + item.getTitle());
    }
    return result.toString();
  }

  public Double makeVote(final Item item, final Double value)
  {
    final Property voted = item.getItemProperty("Voted");
    final Property ratingPoints = item.getItemProperty("RatingPoints");
    final Property idProp = item.getItemProperty("ID");
    final Object id = idProp.getValue();
    if (id == null)
      return 0.0;
    Integer newVoted = voted.getValue() == null ? 0 : (Integer) voted
        .getValue();
    Double newRatingValue = ratingPoints.getValue() == null ? 0d
        : (Double) ratingPoints.getValue();
    if (!votedFor((Integer)id))
    {
      newVoted++;
      newRatingValue += value;
      addVoted((Integer)id);
      voted.setValue(newVoted);
      ratingPoints.setValue(newRatingValue);
      DatabaseHelper.get().updateRating(id, newVoted, newRatingValue);
    }
    return newRatingValue / newVoted;
  }

  public BookStoreItem removeFromCart(final Item item)
  {
    final BookStoreItem bean = DataUtils.getBeanByItem(item);
    final BeanItem<BookStoreItem> bi = cartContainer.getItem(bean);
    if (bi == null)
      return bean;
    bi.getBean().increaseQuantity(-1);
    if (bi.getBean().getQuantity() <= 0)
      cartContainer.removeItem(bean);
    return bean;
  }

  public boolean votedFor(final Integer id)
  {
    return votedIds.contains(id);
  }
}
